home *** CD-ROM | disk | FTP | other *** search
- /* map16bpp.c
- * AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
- * LICENSE: FreeWare, Copyright (c) 1995 Cy Booker
- * PURPOSE: low level 16 bit colour routines
- */
-
- #include "gif2rpc:map16bpp.h"
-
- #include <assert.h>
-
- #include "OS:macros.h"
-
-
-
- /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- #define MINIMISE(d, v) if ((d) >= ((v)+1)) { (d) = (v); } else
- #define MAXIMISE(d, v) if ((d) < (v)) { (d) = (v); } else
-
-
-
- /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- extern bits map_scaled_rgb_to_16bpp_colour_quick(
- rgbtupleout *out,
- int red,
- int grn,
- int blu) {
- int out_red, out_grn, out_blu;
- int colour_number;
- int t;
-
- t = 0xffff; /* helps the compiler */
- MINIMISE(red, t);
- MINIMISE(grn, t);
- MINIMISE(blu, t);
- MAXIMISE(red, 0);
- MAXIMISE(grn, 0);
- MAXIMISE(blu, 0);
-
- /*
- * a first approximation is just the 5 most significant bits
- * with appropriate rounding we get a better approximation at the cost of
- * two ARM instruction per axis
- */
- out_red = ((red * 0x1f) + 0x8000) >> 16;
- out_grn = ((grn * 0x1f) + 0x8000) >> 16;
- out_blu = ((blu * 0x1f) + 0x8000) >> 16;
-
- colour_number = out_red | (out_grn << 5) | (out_blu << 10);
-
- if (out) {
- /*
- * now inline scaling of (0xffff / 0x1f)
- * note that rather than |'ing shifted right 5, 10, then 15 we just do 10, then 5
- *
- * %abcd e000 0000 0000
- * %abcd e000 00ab cde0
- * %abcd eabc deab cdea
- */
- out_red <<= 16 - 5; out_red |= out_red >> 10; out_red |= out_red >> 5;
- out_grn <<= 16 - 5; out_grn |= out_grn >> 10; out_grn |= out_grn >> 5;
- out_blu <<= 16 - 5; out_blu |= out_blu >> 10; out_blu |= out_blu >> 5;
-
- red -= out_red;
- grn -= out_grn;
- blu -= out_blu;
-
- out->colour.red = red;
- out->colour.grn = grn;
- out->colour.blu = blu;
- }
-
- return colour_number;
- }
-
-
-
-